From: Georges Basile Stavracas Neto Date: Thu, 25 Jun 2020 19:51:30 +0000 (-0300) Subject: appDisplay: Use a drag monitor to check for out-of-dialog drags X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~684^2^2~99 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=d93b51e1354460be0ef9670013f7f06527af5f3c;p=gnome-shell.git appDisplay: Use a drag monitor to check for out-of-dialog drags When the app folder dialog handles a drag hover, it starts a timeout to popdown if dragging outside the "real" dialog area. However, when dragging inside it, BaseAppView handles all drag hover events which would disarm the popdown timeout. In cases like this, it's almost impossible to prevent the timeout from triggering, which always pops down the dialog. Add a drag monitor when handling any drag hover (which only happens when dragging outside the folder's icon grid); and eventually disarm the popdown timeout from the monitor's motion event. Remove the drag monitor when dragging over the folder dialog again. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284 --- diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 44c4f3f5f..fdbfef677 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -2011,6 +2011,7 @@ var AppFolderDialog = GObject.registerClass({ this._grabHelper.addActor(Main.layoutManager.overviewGroup); this.connect('destroy', this._onDestroy.bind(this)); + this._dragMonitor = null; this._sourceMappedId = 0; this._popdownTimeoutId = 0; this._needsZoomAndFade = false; @@ -2224,6 +2225,22 @@ var AppFolderDialog = GObject.registerClass({ this._needsZoomAndFade = false; } + _removeDragMonitor() { + if (!this._dragMonitor) + return; + + DND.removeDragMonitor(this._dragMonitor); + this._dragMonitor = null; + } + + _removePopdownTimeout() { + if (this._popdownTimeoutId === 0) + return; + + GLib.source_remove(this._popdownTimeoutId); + this._popdownTimeoutId = 0; + } + _onDestroy() { if (this._isOpen) { this._isOpen = false; @@ -2236,10 +2253,8 @@ var AppFolderDialog = GObject.registerClass({ this._sourceMappedId = 0; } - if (this._popdownTimeoutId > 0) { - GLib.source_remove(this._popdownTimeoutId); - this._popdownTimeoutId = 0; - } + this._removePopdownTimeout(); + this._removeDragMonitor(); } vfunc_allocate(box) { @@ -2306,19 +2321,41 @@ var AppFolderDialog = GObject.registerClass({ y < childAllocation.y2; } + _setupDragMonitor() { + if (this._dragMonitor) + return; + + this._dragMonitor = { + dragMotion: dragEvent => { + if (this._withinDialog(dragEvent.x, dragEvent.y)) { + this._removePopdownTimeout(); + this._removeDragMonitor(); + } + return DND.DragMotionResult.CONTINUE; + }, + }; + DND.addDragMonitor(this._dragMonitor); + } + + _setupPopdownTimeout() { + if (this._popdownTimeoutId > 0) + return; + + this._popdownTimeoutId = + GLib.timeout_add(GLib.PRIORITY_DEFAULT, POPDOWN_DIALOG_TIMEOUT, () => { + this._popdownTimeoutId = 0; + this.popdown(); + return GLib.SOURCE_REMOVE; + }); + } + handleDragOver(source, actor, x, y) { if (this._withinDialog(x, y)) { - if (this._popdownTimeoutId > 0) { - GLib.source_remove(this._popdownTimeoutId); - this._popdownTimeoutId = 0; - } - } else if (this._popdownTimeoutId === 0) { - this._popdownTimeoutId = - GLib.timeout_add(GLib.PRIORITY_DEFAULT, POPDOWN_DIALOG_TIMEOUT, () => { - this._popdownTimeoutId = 0; - this.popdown(); - return GLib.SOURCE_REMOVE; - }); + this._removePopdownTimeout(); + this._removeDragMonitor(); + } else { + this._setupPopdownTimeout(); + this._setupDragMonitor(); } return DND.DragMotionResult.NO_DROP;